package com.yuyue.springFramework.note16;

import com.alibaba.druid.pool.DruidDataSource;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.function.Consumer;

/**
 * 《Spring-16 编码方式实现事务》文章代码
 *  文章地址：https://mp.weixin.qq.com/s/Cl9qlVr5-0nD0whnFO0MQA
 */
public class Note16Test {
    @Test
    //平台事务管理
    public void fun1(){
        //获取容器，容器中定义了数据源
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("ApplicationContext07.xml");
        DruidDataSource dataSource = applicationContext.getBean("dataSource", DruidDataSource.class);

        //定义 JdbcTemplate
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

        //获取普通事务管理器，与JdbcTemplate使用同一个数据源
        PlatformTransactionManager transactionManager = new DataSourceTransactionManager(dataSource);
        //获取默认事务定义
        TransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
        //获取事务状态，开启事务
        TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition);

        try{
            //第一处更新
            jdbcTemplate.update("update person set name = ? where id = 1", "我自由了");

            //报错
            System.out.println(1/0);

            //第二处更新
            jdbcTemplate.update("update person set name = ? where id = 2", "我也自由了");

            //提交事务
            transactionManager.commit(transactionStatus);
        }catch (Exception e){
            //回滚事务
            transactionManager.rollback(transactionStatus);
            //打印错误信息
            System.out.println(e.getMessage());
        }

        //查询操作结果
        System.out.println(jdbcTemplate.queryForList("select name from person where id in(?, ?)", new String[]{"1", "2"}));
    }

    @Test
    //事务模板，无返回
    public void fun2(){
        //获取容器，容器中定义了数据源
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("ApplicationContext07.xml");
        DruidDataSource dataSource = applicationContext.getBean("dataSource", DruidDataSource.class);

        //定义 JdbcTemplate
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

        //获取平台事务管理器，与JdbcTemplate使用同一个数据源
        PlatformTransactionManager transactionManager = new DataSourceTransactionManager(dataSource);
        //获取默认事务定义
        TransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
        /**
         * 定义事务模板
         */
        TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager, transactionDefinition);

        try {
            //不带返回值
            transactionTemplate.executeWithoutResult(new Consumer<TransactionStatus>() {
                @Override
                public void accept(TransactionStatus transactionStatus) {
                    //第一处更新
                    jdbcTemplate.update("update person set name = ? where id = 1", "我变模板了");

                    //报错
                    //System.out.println(1/0);
                    //将事务状态标注为回滚状态
                    //transactionStatus.setRollbackOnly();

                    //第二处更新
                    jdbcTemplate.update("update person set name = ? where id = 2", "我也变模板了");
                }
            });
        }catch (Exception e){
            //打印错误信息
            System.out.println(e.getMessage());
        }

        //查询操作结果
        System.out.println(jdbcTemplate.queryForList("select name from person where id in(?, ?)", new String[]{"1", "2"}));
    }

    @Test
    //事务模板，有返回
    public void fun3(){
        //获取容器，容器中定义了数据源
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("ApplicationContext07.xml");
        DruidDataSource dataSource = applicationContext.getBean("dataSource", DruidDataSource.class);

        //定义 JdbcTemplate
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

        //获取平台事务管理器，与JdbcTemplate使用同一个数据源
        PlatformTransactionManager transactionManager = new DataSourceTransactionManager(dataSource);
        //获取默认事务定义
        TransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
        /**
         * 定义事务模板
         */
        TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager, transactionDefinition);

        try {
            //带返回值执行
            Integer i = transactionTemplate.execute(new TransactionCallback<Integer>() {

                @Override
                public Integer doInTransaction(TransactionStatus status) {
                    //第一处更新
                    Integer i = jdbcTemplate.update("update person set name = ? where id = 1", "我变返回值了");

                    //报错
                    //System.out.println(1/0);
                    //将事务状态标注为回滚状态
                    //status.setRollbackOnly();

                    //第二处更新
                    i += jdbcTemplate.update("update person set name = ? where id = 2", "我也变返回值了");
                    return i;
                }
            });

            System.out.println("更新了 " + i + " 条");
        }catch (Exception e){
            //打印错误信息
            System.out.println(e.getMessage());
        }

        //查询操作结果
        System.out.println(jdbcTemplate.queryForList("select name from person where id in(?, ?)", new String[]{"1", "2"}));
    }
}
